home *** CD-ROM | disk | FTP | other *** search
- package sub_arctic.lib;
-
- import sub_arctic.input.event;
- import sub_arctic.input.callback_object;
- import sub_arctic.input.inout_draggable;
- import sub_arctic.input.pressable;
-
- import sub_arctic.output.color_pair;
- import sub_arctic.output.loaded_image;
- import sub_arctic.output.drawable;
- import sub_arctic.output.style;
- import sub_arctic.output.style_manager;
-
- import sub_arctic.lib.sub_arctic_error;
-
- import java.awt.Point;
- import java.awt.Dimension;
- import java.awt.Image;
- import java.awt.Font;
- import java.awt.FontMetrics;
- import java.awt.Color;
-
- /**
- * This class implements a button in the current style. By default, buttons
- * are not resizable, they have an intrinsic size. You can use the method
- * set_autosize(false) if you desire the button to be resizable to any size.
- *
- * @author Scott Hudson
- */
- public class button extends multi_button implements inout_draggable,pressable {
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Constructor where we expect you to position the object
- * with constraints. The image set given here must contain either one or
- * two images. The one at index 0 will be used for normal appearance, and
- * the one at index 1 (if any) will be used for highlight when the button
- * is being "depressed".
- *
- * @param loaded_image[] look the two images to display for this button.
- * @param callback_object call_obj the object to run the callbacks on.
- */
- public button(
- loaded_image[] look,
- callback_object call_obj)
- {
- super(0,0,null,null,call_obj);
-
- /* make sure the image set is usable */
- if (look == null || look.length == 0 || look.length > 2)
- throw new sub_arctic_error("Unusable image set passed to button()");
-
- /* if we only have one image, put in a second duplicate entry */
- if (look.length == 1)
- {
- loaded_image[] lk = new loaded_image[2];
- lk[0] = look[0];
- lk[1] = look[1];
- look = lk;
- }
-
- /* set the stuff up with the parent */
- set_looks(look,null);
-
-
- /* calculate correct initial size */
- calc_size();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Full constructor. The image set given here must contain either one or
- * two images. The one at index 0 will be used for normal appearance, and
- * the one at index 1 (if any) will be used for highlight when the button
- * is being "depressed".
- *
- * @param int x the x position of the interactor.
- * @param int y the y position of the interactor.
- * @param loaded_image[] look the two images to display for this button.
- * @param callback_object call_obj the object to run the callbacks on.
- */
- public button(
- int x,
- int y,
- loaded_image[] look,
- callback_object call_obj)
- {
- super(x,y,null,null,call_obj);
-
- /* make sure the image set is usable */
- if (look == null || look.length == 0 || look.length > 2)
- throw new sub_arctic_error("Unusable image set passed to button()");
-
- /* if we only have one image, put in a second duplicate entry */
- if (look.length == 1)
- {
- loaded_image[] lk = new loaded_image[2];
- lk[0] = look[0];
- lk[1] = look[1];
- look = lk;
- }
-
- set_looks(look,null);
-
- /* calculate correct initial size */
- calc_size();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Constructor based on a textual label. Images will be constructed
- * using the style system.
- *
- * @param int x the x position of the interactor.
- * @param int y the y position of the interactor.
- * @param String label the text to draw on the button.
- * @param callback_object call_obj the callback object.
- */
- public button(
- int x,
- int y,
- String label,
- callback_object call_obj)
- {
- super(x,y,null,null,call_obj);
-
- /* sanity check */
- if (label==null) {
- label="";
- }
- /* save the text for a second */
- _text= label;
- _picture=null;
-
- /* calculate correct initial size */
- style_changed();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Constructor based on a loaded_image and we assume you will
- * use constraints to position it. We build the button via the
- * style system.
- *
- * @param loaded_image img the image to draw on the button
- * @param callback_object call_obj the callback object.
- */
- public button(
- loaded_image img,
- callback_object call_obj)
- {
- super(0,0,null,null,call_obj);
-
- /* set the right values */
- _picture=img;
- _text=null;
-
- /* calculate correct initial size */
- style_changed();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Constructor based on a textual label and we assume you will
- * use constraints to position it. We build the button via the
- * style system.
- *
- * @param String label the text to draw on the button
- * @param callback_object call_obj the callback object.
- */
- public button(
- String label,
- callback_object call_obj)
- {
- super(0,0,null,null,call_obj);
-
- /* save the other instance vars */
- _callback_obj = call_obj;
-
- /* sanity check */
- if (label==null) {
- label="";
- }
- /* save the text for a second */
- _text= label;
-
- /* calculate correct initial size */
- style_changed();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Border around text horizontally
- */
- protected int _x_border = 10;
-
- /**
- * Retrieve the horizontal border
- * @return int the horizontal border
- */
- public int x_border() {
- return _x_border;
- }
-
- /**
- * Set the horizontal border.
- * @param int x new amount of horizontal border.
- */
- public void set_x_border(int x) {
- _x_border=x;
- style_changed();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /** Border around text vertically */
- protected int _y_border = 5;
-
- /**
- * Retrieve the vertical border
- * @return int the vertical border
- */
- public int y_border() {
- return _y_border;
- }
-
- /**
- * Set the vertical border.
- * @param int y new amount of vertical border.
- */
- public void set_y_border(int y) {
- _y_border=y;
- style_changed();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Keep a hold the font for textual gables used by this object.
- */
- protected Font _font=null;
-
- /**
- * Retrieve this object's font. If you haven't specified a font,
- * you get the system default font.
- */
- public Font font() {
- if (_font==null) {
- return style_manager.default_font();
- }
- return _font;
- }
-
- /**
- * Set the font for this object.
- * @param Font f the new font to use on this object
- */
- public void set_font(Font f) {
- _font=f;
- style_changed();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This variable holds the text we are about to render onto
- * this button. Note that this is not consulted once we
- * have rendered the image the first time.
- */
- protected String _text=null;
-
- /**
- * Get the text of this button. Note: This value might be null
- * if you are currently displaying an image on this button.
- * If you supplied two of your own images to make this button,
- * both the value of text() and the value of picture() will
- * be null, since you did not use the normal style interface
- * to create your buttons.
- * @return String the current text string of the button (or null)
- */
- public String text() { return _text;}
-
- /**
- * Set this button to display a string.
- * @param String l the new label
- */
- public void set_text(String l) {
- /* validity check */
- if (l==null) {
- l="";
- }
- /* set the text and the picture */
- _text=l;
- _picture=null;
- style_changed();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Store the picture (if any) we want on this button.
- */
- protected loaded_image _picture=null;
-
- /**
- * Return the picture we are using for this button. This might be
- * null if we are currently displaying a string.
- * @return loaded_image the image we are display on this button or null
- * if no image has been supplied
- */
- public loaded_image picture() {
- return _picture;
- }
-
- /**
- * Set the current image to display on this button. Note: that you
- * should probably be using something on a transparent background if
- * don't want this to interfere the style system.
- *
- * @param loaded_image p the new picture to put on this button.
- */
- public void set_picture(loaded_image p) {
- _picture=p;
- _text=null;
- style_changed();
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This function gets called to generate the images for this button
- * based on the current style parameters.
- */
- public void style_changed() {
- loaded_image img[];
- style cs=style_manager.current_style();
- int x_off, y_off;
-
- /* check to see if we are autosizing or not */
- if (_autosize) {
- /* we are autosizing...are we doing a string label? */
- if (_text!=null) {
- /* get the new size */
- img=cs.button_make_images(_text,font(),_x_border,_y_border,false);
- } else {
- if (_picture!=null) {
- img=cs.button_make_images(_picture.width(), _picture.height(),
- _x_border, _y_border, false);
-
- /* figure out how much to shift the thing*/
- x_off=cs.button_x_shift();
- y_off=cs.button_y_shift();
- /* now put the picture on them */
- img[0].get_drawable().drawImage(_picture,x_off+_x_border,
- y_off+_y_border);
- img[1].get_drawable().drawImage(_picture,x_off+_x_border,
- y_off+_y_border);
- } else {
- /* probably a programming error */
- throw new sub_arctic_error("Unable to find a either a text " +
- "label or a picture to display on "+
- "this button! ");
- }
- }
- } else {
- /* we are not autosizing, use the size of this object ... we
- subtract off the beveling areas...*/
- img=cs.button_make_images(w()-(2*cs.button_x_shift()),
- h()-(2*cs.button_y_shift()),
- 0,0,false);
-
- /* do the work of drawing the stuff */
- draw_label(img);
- }
- set_looks(img,null);
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Draw either the text or the image of the object on the button.
- * This is here primarily to allow subclass writers to put the
- * label somewhere other than in the middle. This is ONLY called
- * we are not in autosize mode (since it only makes sense to put
- * the label in one place in autosize mode).
- *
- * @param loaded_image[] img the base images to draw on
- */
- public void draw_label(loaded_image[] img) {
- FontMetrics metrics=manager.get_metrics(font());
- int sw, fh, x, y;
- drawable d;
-
- /* is it text */
- if (_text!=null) {
- sw=metrics.stringWidth(text());
- fh=metrics.getHeight() - metrics.getLeading();
- /* x or y might be negative, but this will show the object as "in
- * the middle" of the button anyway */
- x=(w()-sw)/2;
- y=(h()-fh)/2;
- /* get the drawables and slap this stuff down */
- d=img[0].get_drawable();
- d.setFont(font());
- d.setColor(style_manager.default_color_scheme().foreground());
- d.drawString(_text,x,y+metrics.getAscent());
- d=img[1].get_drawable();
- d.setFont(font());
- d.setColor(style_manager.default_color_scheme().foreground());
- d.drawString(_text,x,y+metrics.getAscent());
- } else {
- /* must be a picture */
- x=(w()-_picture.width())/2;
- y=(h()-_picture.height())/2;
- /* again, these might be negative, but centering is still what you get */
- d=img[0].get_drawable();
- d.drawImage(_picture,x,y);
- d=img[1].get_drawable();
- d.drawImage(_picture,x,y);
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * We need to override the end behavior of the multi-button to make
- * sure we always end up in the right state.
- *
- * @param event evt the event to be dispatched.
- * @param boolean ended_inside true if the drag ended inside the object.
- * @param Object user_info the object passed to the inout_drag agent when
- * this object came into the focus set.
- * @return boolean true if this event has been handled.
- */
- public boolean inout_drag_end(
- event evt,
- boolean ended_inside,
- Object user_info)
- {
- super.inout_drag_end(evt,ended_inside,user_info);
- /* if we are not in state zero, we should be */
- if (cur_state()!=0) {
- set_cur_state(0);
- }
- return true;
-
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This is the storage for the autosize variable.
- */
- protected boolean _autosize=true;
-
- /**
- * Retrieve the current state of autosize.
- * @return boolean true if the object is autosized (and thus not resizable)
- */
- public boolean autosize() { return _autosize;}
-
- /**
- * Set the current state of the autosize variable. If you change the
- * state from non-autosized (false) to autosized (true) the button
- * will immediately autosize itself. If you change the state to
- * non-autosized from autosized, no immediate redraw is requested
- * and the object will continue at its current size unless that
- * is changed.
- */
- public void set_autosize(boolean a) {
- /* no work to do */
- if (a==_autosize) {
- return;
- }
- /* save it */
- _autosize=a;
- /* is it currently false and now true? */
- if (a==true) {
- /* update the display */
- style_changed();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * We override the intrinsic constraint function because sometimes
- * we have intrinsic constraints (when autosize is on) and sometimes
- * we don't.
- * @return int a constant representing what (if any) our intrinsic
- * constraints are.
- */
- public int intrinsic_constraints() {
- if (_autosize) {
- return W|H;
- } else {
- return 0;
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * This function computes the natural size of a button. This is useful
- * when you want to walk down a list (or more likely, column) of buttons
- * and find out which of them has the largest natural size and then
- * set all of them to that size.
- *
- * @return Dimension the size (in pixels) of this button at its natural size
- */
- public Dimension natural_size() {
- loaded_image img[]=null;
- style cs=style_manager.current_style();
-
- if (_text!=null) {
- /* get the new size */
- img=cs.button_make_images(_text,font(),_x_border,_y_border,false);
- } else {
- if (_picture!=null) {
- img=cs.button_make_images(_picture.width(), _picture.height(),
- _x_border, _y_border,false);
- }
- }
- return new Dimension(img[0].width(),img[0].height());
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * We have to override how set_intrinsic_size works here, because
- * sometimes we have an intrinsic size and sometimes we don't.
- * Multi-button (our parent) calls this code to tell the button
- * that it can't be resized, but we know that it can in some
- * cases...
- *
- * @param int wv the intrinsic width value
- * @param int hv the intrinsic height value
- */
- public void set_intrinsic_size(int wv, int hv)
- {
- /* we only want this if we are automatically sizing */
- if (_autosize) {
- super.set_intrinsic_size(wv,hv);
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Trap calls to set_raw_w() which will change the width. If we are
- * not autosizing, we want to recalculate the images.
- * @param int w the new width value
- */
- public void set_raw_w(int w)
- {
- /* we always want the parent behavior first */
- super.set_raw_w(w);
- if (!_autosize) {
- style_changed();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
-
- /**
- * Trap calls to set_raw_h() which will change the height. If we are
- * not autosizing, we want to recalculate the images.
- * @param int h the new height value
- */
- public void set_raw_h(int h)
- {
- /* we always want the parent behavior first */
- super.set_raw_h(h);
- if (!_autosize) {
- style_changed();
- }
- }
-
- /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
- }
- /*=========================== COPYRIGHT NOTICE ===========================
-
- This file is part of the subArctic user interface toolkit.
-
- Copyright (c) 1996 Scott Hudson and Ian Smith
- All rights reserved.
-
- The subArctic system is freely available for most uses under the terms
- and conditions described in
- http://www.cc.gatech.edu/gvu/ui/sub_arctic/sub_arctic/doc/usage.html
- and appearing in full in the lib/interactor.java source file.
-
- The current release and additional information about this software can be
- found starting at: http://www.cc.gatech.edu/gvu/ui/sub_arctic/
-
- ========================================================================*/
-